DB Schema 权限体系
uniCloud 的 DB Schema 权限系统是理解 uni-admin 权限机制的关键。它采用了类似 CASL(CASL Ability)的策略权限控制,在数据库层面实现了精细的访问控制。
权限控制的两个维度
| 维度 | 控制范围 | 支持的操作 |
|---|---|---|
| 表级权限 | 整张数据表 | read, create, update, delete, count |
| 字段级权限 | 表中的特定字段 | read, write(write 包含 update 和 delete) |
权限规则的校验逻辑:操作类型 + 角色条件 → 匹配则通过,不匹配则拒绝。
Admin 角色的特殊地位
admin 角色(超级管理员)不受 DB Schema 权限限制,拥有所有数据的完整读写权限。这个逻辑写在 uni-id 的中间件代码中:
uni-id-pages/cloud-functions/middleware/access-control.js
text
关键逻辑在 isAccessAllowed 方法中:
// 伪代码
function isAccessAllowed(user) {
if (user.role.includes('admin')) {
return true // admin 角色直接放行,不做任何拦截
}
// 其他角色继续执行权限校验逻辑...
}
javascript
表级权限控制
在 Schema 的 permission 字段中配置整张表的增删改查权限:
{
"permission": {
"read": true,
"create": "auth.permission.includes('create-user')",
"update": "auth.permission.includes('update-user')",
"delete": false,
"count": true
}
}
json
count 是表级特有的权限——控制是否允许对该表执行统计计数操作。很多开发者忽略了 count 权限,导致管理后台首页的统计组件报错。
字段级权限控制
在每个字段的定义中,可以单独配置 read 和 write 权限。这是导致"权限校验未通过"错误的核心原因。
{
"properties": {
"username": {
"type": "string",
"permission": {
"read": "read-uni-id-users",
"write": false
}
},
"nickname": {
"type": "string",
"permission": {
"read": true,
"write": "auth.permission.includes('update-user')"
}
}
}
}
json
字段权限的值有三种形式:
| 值 | 含义 |
|---|---|
true | 任何人可读写 |
false | 任何人不可读写 |
"permission-id" | 拥有该权限标识的用户可读写 |
当值为字符串(如 "read-uni-id-users")时,系统会检查当前用户的 auth.permission 数组中是否包含该字符串。
auth.permission 变量
auth.permission 是 DB Schema 权限系统中的内置变量,代表当前用户所有角色对应的权限标识的合集。
用户 → 拥有角色 member → 角色包含权限 [read-uni-id-users, read-uni-id-roles]
→ auth.permission = ['read-uni-id-users', 'read-uni-id-roles']
text
条件判断 "read-uni-id-users" in auth.permission 实际上就是检查用户的权限数组中是否包含该标识。
uni-admin 项目的权限 Bug
问题一:Schema 权限标识缺失
uni-admin 模板项目初始化后,数据库中的 Schema 已经定义了字段级权限标识(如 read-uni-id-users),但 uni-id-permissions 表中并没有预置这些权限数据。导致即使按照官方文档创建了基本权限,普通用户仍然无法读取数据。
解决方法:逐一检查报错的表,在权限管理中添加对应的权限标识。
问题二:两个项目的 Schema 不同步
uni-starter 和 uni-admin 关联同一个云空间后,两边的 database/ 目录中的 Schema 文件可能不一致。例如 opendb-app-list.schema.json 在 uni-admin 中 read 和 count 为 true,但在 uni-starter 中全部为 false。
同步方法:
- 在 uni-admin 中解除云空间关联
- 单独上传 uni-admin 的 DB Schema 到云端
- 在 uni-starter 中右键
databases→ 下载 DB Schema,同步云端最新配置 - 重新关联云空间
关键点:本地 HBuilderX 中"关联其他项目的云空间"只是共享运行时环境,本地的 Schema 文件不会自动同步。修改了一端的 Schema 后,另一端需要手动下载更新。
问题三:count 权限被忽略
opendb-app-list 表的 count 权限在 uni-starter 的 Schema 中默认为 false,导致普通用户无法执行计数查询,首页统计组件报错。
解决方法:将该表的 count 权限设为 true,并上传 Schema 到云端。
权限排查思路
遇到"权限校验未通过"错误时,按以下步骤排查:
- 打开浏览器控制台,查看报错信息中的集合名称(如
uni-stat-result) - 找到该集合对应的 Schema 文件
- 检查表级权限和字段级权限的
read值 - 如果
read值是权限标识字符串,确认该标识已添加到uni-id-permissions表中 - 确认当前用户的角色已包含该权限标识
- 修改 Schema 后记得上传到云端覆盖
↑